package com.ms.service.module.analysisgroup;

import java.math.BigDecimal;
import java.math.RoundingMode;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.xpec.c4.game.common.Helper;

/**
 * 遊戲館收支資料 
 */
public class GameRevenueAndExpenditureData {
	
	/** log object */
	private static final Log log = LogFactory.getLog(GameRevenueAndExpenditureData.class);
	
	/**
	 * 正式警示觸發比率 = totalScore + totalJP(支出) / totalBet(收入)
	 */
	public static final BigDecimal FORMAL_ALERT_RATE = new BigDecimal("1.00000");
	
	/**
	 * 正式幣警示觸發差額 = (totalScore + totalJP)(支出) - totalBet(收入)
	 */
	public static final BigDecimal FORMAL_ALERT_DIFFERENCE = new BigDecimal(5000000);

	/**正式幣總押注**/
	private BigDecimal totalBetFormal;
	
	/**正式幣總得分**/
	private BigDecimal totalScoreFormal;
	
	/**正式幣總JP**/
	private BigDecimal totalJP;
	
	/**使用卡片得分*/
	private BigDecimal totalCardScore;
	
	/**正式幣警報標記**/
	private boolean isFormalAlertAlready;
	
	
	/**
	 * 試玩警示觸發比率 = totalScore(支出) / totalBet(收入)<br>
	 */
	public static final BigDecimal TRIAL_ALERT_RATE = new BigDecimal("1.00000");
	
	/**
	 * 體驗幣警示觸發差額 = totalScore(支出) - totalBet(收入)
	 */
	public static final BigDecimal TRIAL_ALERT_DIFFERENCE = new BigDecimal(5000000);

	/**體驗幣總押注**/
	private BigDecimal totalBetTrial;
	
	/**體驗幣總得分**/
	private BigDecimal totalScoreTrial;
	
	/**體驗幣警報標記**/
	private boolean isTrialAlertAlready;
	
	public GameRevenueAndExpenditureData(){
		this.totalBetFormal = BigDecimal.ZERO;
		this.totalScoreFormal = BigDecimal.ZERO;
		this.totalJP = BigDecimal.ZERO;
		this.totalCardScore = BigDecimal.ZERO;
		this.isFormalAlertAlready = false;
		this.totalBetTrial = BigDecimal.ZERO;
		this.totalScoreTrial = BigDecimal.ZERO;
		this.isTrialAlertAlready = false;
	}
	
	/**
	 * 比率是否達到警示標準 (暫時沒用到)
	 */
	public boolean isRateAlert(boolean isFormal){
		try{
			BigDecimal payout;
			BigDecimal income;
			BigDecimal alertRate;
			if(isFormal){
				payout = Helper.add(totalScoreFormal, totalJP, totalCardScore);
				income = totalBetFormal;
				alertRate = FORMAL_ALERT_RATE;
			}
			else{
				payout = new BigDecimal(String.valueOf(totalScoreTrial));
				income = new BigDecimal(String.valueOf(totalBetTrial));
				alertRate = TRIAL_ALERT_RATE;
			}
			
			//理論上押注不可能是0，這邊是做保險一點的判斷，避免除數為0
			if(income.compareTo(new BigDecimal("0.0")) == 0){
				if(log.isErrorEnabled()){
					log.error("can't calculate alert rate because income(totalBet) = 0"); 
				}
				return false;
			}
			
			//四捨五入取到小數第五位
			BigDecimal judgeRate = payout.divide(income, 5, RoundingMode.HALF_UP);
			//如果judgeRate>ALERT_RATE時
			if(judgeRate.compareTo(alertRate) == 1){
				return true;
			}
			else return false;
		}
		//有可能轉不了BigDecimal
		catch(Exception e){
			if(log.isErrorEnabled()){
				log.error("can't hadle isRateAlert judgement");				
			}
			return false;
		}
	}

	/**
	 * 收支差額是否達到警示標準
	 */
	public boolean isDifferenceAlert(boolean isFormal){
		try {
			if(isFormal){
				BigDecimal payout = Helper.add(totalScoreFormal, totalJP, totalCardScore);
				BigDecimal realPayout = Helper.sub(payout, totalBetFormal);
				if(Helper.isGreaterEqual(realPayout, FORMAL_ALERT_DIFFERENCE))
					return true;
				else return false;
			}
			else{
				BigDecimal payout = Helper.sub(totalScoreTrial, totalBetFormal);
				if(Helper.isGreaterEqual(payout, TRIAL_ALERT_DIFFERENCE))
					return true;
				else return false;
			}
		}
		//有可能超過long計算嗎..
		catch (Exception e) {
			if(log.isErrorEnabled()){
				log.error("can't handle isDifferenceAlert judgement");
			}
			return false;
		}
	}
	
	
	public BigDecimal getTotalBetFormal() {
		return totalBetFormal;
	}


	public void setTotalBetFormal(BigDecimal totalBetFormal) {
		this.totalBetFormal = totalBetFormal;
	}


	public BigDecimal getTotalScoreFormal() {
		return totalScoreFormal;
	}


	public void setTotalScoreFormal(BigDecimal totalScoreFormal) {
		this.totalScoreFormal = totalScoreFormal;
	}


	public BigDecimal getTotalJP() {
		return totalJP;
	}


	public void setTotalJP(BigDecimal totalJP) {
		this.totalJP = totalJP;
	}


	public boolean isFormalAlertAlready() {
		return isFormalAlertAlready;
	}


	public void setFormalAlertAlready(boolean isFormalAlertAlready) {
		this.isFormalAlertAlready = isFormalAlertAlready;
	}


	public BigDecimal getTotalBetTrial() {
		return totalBetTrial;
	}


	public void setTotalBetTrial(BigDecimal totalBetTrial) {
		this.totalBetTrial = totalBetTrial;
	}


	public BigDecimal getTotalScoreTrial() {
		return totalScoreTrial;
	}


	public void setTotalScoreTrial(BigDecimal totalScoreTrial) {
		this.totalScoreTrial = totalScoreTrial;
	}

	public boolean isTrialAlertAlready() {
		return isTrialAlertAlready;
	}

	public void setTrialAlertAlready(boolean isTrialAlertAlready) {
		this.isTrialAlertAlready = isTrialAlertAlready;
	}

	public BigDecimal getTotalCardScore() {
		return totalCardScore;
	}

	public void setTotalCardScore(BigDecimal totalCardScore) {
		this.totalCardScore = totalCardScore;
	}

}
